package face.pay.message.handler.event;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import face.pay.AbstractRedis;
import face.pay.constant.CacheKey;
import face.pay.dao.*;
import face.pay.entity.*;
import face.pay.message.entity.event.UserGetCardEvent;
import face.pay.message.handler.AbstractHandler;
import face.pay.util.DateUtil;
import face.pay.util.HttpClientUtil;
import face.pay.util.bean.JavaBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import weixin.popular.api.CardAPI;
import weixin.popular.bean.BaseResult;
import weixin.popular.bean.card.modifystock.ModifyStock;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户领券接口
 */
@Component
@Slf4j
public class UserGetCardEventHandler extends AbstractHandler {


    @Autowired
    CpnCardDetailInfoDao cpnCardDetailInfoDao;

    @Autowired
    CpnCardInfoDao cpnCardInfoDao;

    @Autowired
    CpnActivityInfoDao cpnActivityInfoDao;

    @Autowired
    CpnCardMessageDao cpnCardMessageDao;

    @Autowired
    CpnMarketInfoDao cpnMarketInfoDao;

    @Autowired
    CpnMarketInfoDao marketInfoDao;

    @Autowired
    private AbstractRedis abstractRedis;

    /**
     * 主要功能为
     * 修改优惠券状态 补充信息
     * 库存增加
     *
     * @param map
     * @return
     */
    @Override
    public Boolean doEvent(Map<String, String> map) {

        UserGetCardEvent userGetCardEvent = (UserGetCardEvent) JavaBeanUtils.mapToBeanWithSupper(map, UserGetCardEvent.class);

        String cardCode = userGetCardEvent.getUserCardCode();
        String outerStr = userGetCardEvent.getOuterStr();

        Long cardDetailId = Long.valueOf(outerStr);


        CpnCardDetailInfo cpnCardDetailInfo = this.cpnCardDetailInfoDao.getById(cardDetailId);

        cpnCardDetailInfo.setCode(cardCode);
        cpnCardDetailInfo.setStatus(1);
        /**
         * 领取时间
         */
        String convertTime = DateUtil.dateFormat(new Date());
        cpnCardDetailInfo.setConvertTime(convertTime);

        CpnActivityInfo cpnActivityInfo = this.cpnActivityInfoDao.getByDetailId(cardDetailId);

        Date activityEndTime = DateUtil.dateParse(cpnActivityInfo.getEnd_time(), DateUtil.default_pattern);
        /**
         * 设置优惠券实际失效时间
         * 领取时间+30天 和 活动结束时间 两者最小值
         */
        Date endTime = DateUtil.addDay(new Date(), 30);
        /**
         * 取endTtime(最晚时间) 23;59:59
         */
        endTime = DateUtil.getDayLastTime(endTime);
        if (endTime.after(activityEndTime)) {
            cpnCardDetailInfo.setEndTime(DateUtil.dateFormat(activityEndTime));
        } else {
            cpnCardDetailInfo.setEndTime(DateUtil.dateFormat(endTime));
        }
        /**
         * 更新状态
         */
        this.cpnCardDetailInfoDao.update(cpnCardDetailInfo);

        Integer marketId = cpnCardDetailInfo.getMarketId();

        CpnMarketInfo marketInfo = this.marketInfoDao.getById(marketId);

        //增加库存
        increaseStock(userGetCardEvent);

        //保存并推送用户领取优惠券的消息
        sendCallBackMessage(cpnCardDetailInfo, marketInfo);
        return true;
    }

    /**
     * 保存并推送用户领取优惠券的消息
     */
    private void sendCallBackMessage(CpnCardDetailInfo cardDetailInfo, CpnMarketInfo marketInfo) {
        CpnCardMessage cpnCardMessage = new CpnCardMessage();
        try {

            String security_key = marketInfo.getSecurity_key();
            String market_code = marketInfo.getMarket_code();

            cpnCardMessage.setOrderId(cardDetailInfo.getOrderId());
            cpnCardMessage.setCardDetailId(cardDetailInfo.getId());
            cpnCardMessage.setRefId(cardDetailInfo.getId());
            cpnCardMessage.setType("GETCARD"); //领取优惠券
            cpnCardMessage.setStatus(0);
            cpnCardMessage.setCount(1);
            String nextTime = cpnCardMessage.createNextTime();
            cpnCardMessage.setNextTime(nextTime);
            cpnCardMessage.setUrl(marketInfo.getMessageUrl());


            Map<String, String> signMap = new HashMap<>();
            signMap.put("market_code", market_code);
            String nonceStr = WXPayUtil.generateNonceStr();
            signMap.put("nonceStr", nonceStr);
            String sign = WXPayUtil.generateSignature(signMap, security_key);

            Map<String, Object> paramMap = new HashMap<>();
            Map<String, Object> data = new HashMap<>();
            Map<String, String> body = new HashMap<>();
            body.put("bizCode", cardDetailInfo.getBizCode());
            data.put("body", body);
            data.put("type", "GETCARD");
            paramMap.put("data", data);
            paramMap.put("sign", sign);
            paramMap.put("nonceStr", nonceStr);


            String jsonData = JSON.toJSONString(paramMap);
            log.info("请求参数：" + jsonData);

            String responseStr = HttpClientUtil.doPostJson(marketInfo.getMessageUrl(), jsonData);
            log.info("请求成功，响应结果：" + responseStr);

            if ("SUCCESS".equals(responseStr)) {
                cpnCardMessage.setStatus(1);
            } else {
                cpnCardMessage.setStatus(-1);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.info("推送用户领取优惠券消息出错");
        } finally {
            this.cpnCardMessageDao.insert(cpnCardMessage);
        }
    }

    /**
     * 增加库存
     *
     * @param userGetCardEvent
     */
    private void increaseStock(UserGetCardEvent userGetCardEvent) {
        ModifyStock stock = new ModifyStock();
        String cardId = userGetCardEvent.getCardId();
        stock.setCardId(cardId);
        stock.setIncreaseStockValue(1);
        String access_token = getAccess_token();
        if (access_token == null) {
            log.info("增加库存获取access_token失败!!!!! cardId:{}", cardId);
        }

        BaseResult baseResult = null;
        try {
            baseResult = CardAPI.modifyStock(access_token, stock);
        } catch (Exception e) {
            log.info("增加库存失败!!!! cardId:{} 异常:{}", cardId, e.toString());
        }

        if (baseResult.getErrcode().equals("0")) {
            log.info("增加库存成功 cardId:{}", cardId);
        } else {
            log.info("增加库存失败!!!! cardId:{}", cardId);
        }
    }


    /**
     * 获取token
     *
     * @return
     */
    private String getAccess_token() {
        String str = (String) this.abstractRedis.get(CacheKey.WX_APP_INFO);
        if (str == null) {
            return null;
        }
        CpnWxAppInfo cpnWxAppInfo = null;
        try {
            cpnWxAppInfo = JSONObject.parseObject(str, CpnWxAppInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return cpnWxAppInfo.getAccess_token();
    }
}
